#include "tetris.h"

// 方块形状定义：I, O, T, S, Z, J, L
// 每个方块有4个旋转状态，用4x4矩阵表示
const bool Tetris::SHAPES[7][4][4][4] = {
  // I 型
  {
    { { 0, 0, 0, 0 }, { 1, 1, 1, 1 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } },
    { { 0, 0, 1, 0 }, { 0, 0, 1, 0 }, { 0, 0, 1, 0 }, { 0, 0, 1, 0 } },
    { { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 1, 1, 1, 1 }, { 0, 0, 0, 0 } },
    { { 0, 1, 0, 0 }, { 0, 1, 0, 0 }, { 0, 1, 0, 0 }, { 0, 1, 0, 0 } } },
  // O 型
  {
    { { 0, 1, 1, 0 }, { 0, 1, 1, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } },
    { { 0, 1, 1, 0 }, { 0, 1, 1, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } },
    { { 0, 1, 1, 0 }, { 0, 1, 1, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } },
    { { 0, 1, 1, 0 }, { 0, 1, 1, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } } },
  // T 型
  {
    { { 0, 1, 0, 0 }, { 1, 1, 1, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } },
    { { 0, 1, 0, 0 }, { 0, 1, 1, 0 }, { 0, 1, 0, 0 }, { 0, 0, 0, 0 } },
    { { 0, 0, 0, 0 }, { 1, 1, 1, 0 }, { 0, 1, 0, 0 }, { 0, 0, 0, 0 } },
    { { 0, 1, 0, 0 }, { 1, 1, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 0, 0 } } },
  // S 型
  {
    { { 0, 1, 1, 0 }, { 1, 1, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } },
    { { 0, 1, 0, 0 }, { 0, 1, 1, 0 }, { 0, 0, 1, 0 }, { 0, 0, 0, 0 } },
    { { 0, 0, 0, 0 }, { 0, 1, 1, 0 }, { 1, 1, 0, 0 }, { 0, 0, 0, 0 } },
    { { 1, 0, 0, 0 }, { 1, 1, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 0, 0 } } },
  // Z 型
  {
    { { 1, 1, 0, 0 }, { 0, 1, 1, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } },
    { { 0, 0, 1, 0 }, { 0, 1, 1, 0 }, { 0, 1, 0, 0 }, { 0, 0, 0, 0 } },
    { { 0, 0, 0, 0 }, { 1, 1, 0, 0 }, { 0, 1, 1, 0 }, { 0, 0, 0, 0 } },
    { { 0, 1, 0, 0 }, { 1, 1, 0, 0 }, { 1, 0, 0, 0 }, { 0, 0, 0, 0 } } },
  // J 型
  {
    { { 1, 0, 0, 0 }, { 1, 1, 1, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } },
    { { 0, 1, 1, 0 }, { 0, 1, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 0, 0 } },
    { { 0, 0, 0, 0 }, { 1, 1, 1, 0 }, { 0, 0, 1, 0 }, { 0, 0, 0, 0 } },
    { { 0, 1, 0, 0 }, { 0, 1, 0, 0 }, { 1, 1, 0, 0 }, { 0, 0, 0, 0 } } },
  // L 型
  {
    { { 0, 0, 1, 0 }, { 1, 1, 1, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } },
    { { 0, 1, 0, 0 }, { 0, 1, 0, 0 }, { 0, 1, 1, 0 }, { 0, 0, 0, 0 } },
    { { 0, 0, 0, 0 }, { 1, 1, 1, 0 }, { 1, 0, 0, 0 }, { 0, 0, 0, 0 } },
    { { 1, 1, 0, 0 }, { 0, 1, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 0, 0 } } }
};

// 方块颜色定义
const uint16_t Tetris::COLORS[7] = {
  TFT_CYAN,    // I 型 - 青色
  TFT_YELLOW,  // O 型 - 黄色
  TFT_PURPLE,  // T 型 - 紫色
  TFT_GREEN,   // S 型 - 绿色
  TFT_RED,     // Z 型 - 红色
  TFT_BLUE,    // J 型 - 蓝色
  TFT_ORANGE   // L 型 - 橙色
};

// ========== 初始化与绘制函数 ==========

// 初始化游戏
void Tetris::initGame() {
  // 清空游戏区域
  memset(grid, 0, sizeof(grid));

  // 初始化游戏状态
  score = 0;
  level = 1;
  lines = 0;
  dropInterval = 800;  // 初始下落间隔800ms
  gameOver = false;
  paused = false;

  // 随机生成第一个和下一个方块
  randomSeed(millis());
  currentType = random(TETROMINO_TYPES);
  nextType = random(TETROMINO_TYPES);
  currentRotation = 0;
  currentX = GRID_WIDTH / 2 - 2;
  currentY = 0;

  lastDropTime = millis();
  lastMoveTime = millis();
}

// 获取格子的屏幕X坐标
int Tetris::getPixelX(int gridX) {
  return GAME_OFFSET_X + gridX * BLOCK_SIZE;
}

// 获取格子的屏幕Y坐标
int Tetris::getPixelY(int gridY) {
  return GAME_OFFSET_Y + gridY * BLOCK_SIZE;
}

// 绘制游戏区域边框
void Tetris::drawGameArea(Screen &screen) {
  // 绘制游戏区域边框
  screen.spr.drawRect(GAME_OFFSET_X - 1, GAME_OFFSET_Y - 1, GRID_WIDTH * BLOCK_SIZE + 2, GRID_HEIGHT * BLOCK_SIZE + 2, TFT_WHITE);

  // 绘制预览区域边框
  screen.spr.drawRect(PREVIEW_X - 1, PREVIEW_Y - 1, PREVIEW_SIZE * BLOCK_SIZE + 2, PREVIEW_SIZE * BLOCK_SIZE + 2, TFT_WHITE);
}

// 绘制游戏网格
void Tetris::drawGrid(Screen &screen) {
  for (int y = 0; y < GRID_HEIGHT; y++) {
    for (int x = 0; x < GRID_WIDTH; x++) {
      if (grid[y][x] > 0) {
        // 有方块，绘制对应颜色
        drawGridCell(screen, x, y, COLORS[grid[y][x] - 1]);
      }
    }
  }
}

// 绘制单个网格单元
void Tetris::drawGridCell(Screen &screen, int gridX, int gridY, uint16_t color) {
  int px = getPixelX(gridX);
  int py = getPixelY(gridY);
  screen.spr.fillRect(px, py, BLOCK_SIZE, BLOCK_SIZE, color);
  screen.spr.drawRect(px, py, BLOCK_SIZE, BLOCK_SIZE, TFT_BLACK);
}

// 清除单个网格单元
void Tetris::clearGridCell(Screen &screen, int gridX, int gridY) {
  int px = getPixelX(gridX);
  int py = getPixelY(gridY);
  screen.spr.fillRect(px, py, BLOCK_SIZE, BLOCK_SIZE, TFT_BLACK);
}

// 绘制方块（通用函数）
void Tetris::drawTetromino(Screen &screen, int type, int rotation, int x, int y, uint16_t color) {
  for (int row = 0; row < 4; row++) {
    for (int col = 0; col < 4; col++) {
      if (SHAPES[type][rotation][row][col]) {
        int gridX = x + col;
        int gridY = y + row;
        int px = getPixelX(gridX);
        int py = getPixelY(gridY);
        screen.spr.fillRect(px, py, BLOCK_SIZE, BLOCK_SIZE, color);
        screen.spr.drawRect(px, py, BLOCK_SIZE, BLOCK_SIZE, TFT_BLACK);
      }
    }
  }
}

// 绘制当前方块
void Tetris::drawCurrentTetromino(Screen &screen) {
  drawTetromino(screen, currentType, currentRotation, currentX, currentY, COLORS[currentType]);
}

// 绘制预览方块
void Tetris::drawPreview(Screen &screen) {
  // 清空预览区域
  screen.spr.fillRect(PREVIEW_X, PREVIEW_Y, PREVIEW_SIZE * BLOCK_SIZE, PREVIEW_SIZE * BLOCK_SIZE, TFT_BLACK);

  // 绘制下一个方块（居中显示）
  for (int row = 0; row < 4; row++) {
    for (int col = 0; col < 4; col++) {
      if (SHAPES[nextType][0][row][col]) {
        int px = PREVIEW_X + col * BLOCK_SIZE;
        int py = PREVIEW_Y + row * BLOCK_SIZE;
        screen.spr.fillRect(px, py, BLOCK_SIZE, BLOCK_SIZE, COLORS[nextType]);
        screen.spr.drawRect(px, py, BLOCK_SIZE, BLOCK_SIZE, TFT_BLACK);
      }
    }
  }
}

// 绘制游戏信息
void Tetris::drawInfo(Screen &screen) {
  screen.spr.setTextColor(TFT_WHITE, TFT_BLACK);
  screen.spr.setTextDatum(TL_DATUM);

  // 下一个
  screen.spr.drawString("下一个:", INFO_X, NEXT_Y, 2);

  // 分数
  screen.spr.drawString("分数:", INFO_X, SCORE_Y, 2);
  screen.spr.fillRect(INFO_X, SCORE_V_Y, 60, 16, TFT_BLACK);
  screen.spr.drawNumber(score, INFO_X, SCORE_V_Y, 2);

  // 等级
  screen.spr.drawString("等级:", INFO_X, LEVEL_Y, 2);
  screen.spr.fillRect(INFO_X, LEVEL_V_Y, 60, 16, TFT_BLACK);
  screen.spr.drawNumber(level, INFO_X, LEVEL_V_Y, 2);

  // 消除行数
  screen.spr.drawString("行数:", INFO_X, LINES_Y, 2);
  screen.spr.fillRect(INFO_X, LINES_V_Y, 60, 16, TFT_BLACK);
  screen.spr.drawNumber(lines, INFO_X, LINES_V_Y, 2);

  // 操作说明
  screen.spr.setTextColor(TFT_CYAN, TFT_BLACK);
  screen.spr.drawString("操作:", INFO_X, CONTROL_Y, 2);
  screen.spr.setTextColor(TFT_WHITE, TFT_BLACK);

  String _controlName[5] = { "左/右", "下:移动", "O:旋转", "A:暂停", "X:退出" };
  for (int i = 0; i < 5; i++) {
    screen.spr.drawString(_controlName[i], INFO_X, CONTROL_C_Y + (20 * i + 1), 1);
  }
}

// 绘制游戏结束界面
void Tetris::drawGameOver(Screen &screen) {
  screen.spr.fillRect(20, 100, 100, 80, TFT_RED);
  screen.spr.drawRect(20, 100, 100, 80, TFT_WHITE);
  screen.spr.setTextColor(TFT_WHITE, TFT_RED);
  screen.spr.setTextDatum(CC_DATUM);
  screen.spr.drawString("GAME", 70, 120, 4);
  screen.spr.drawString("OVER", 70, 145, 4);
  screen.spr.setTextDatum(TL_DATUM);
  screen.spr.setTextColor(TFT_WHITE, TFT_BLACK);
}

// ========== 游戏逻辑函数 ==========

// 检查方块是否可以移动到指定位置
bool Tetris::canMove(int type, int rotation, int x, int y) {
  for (int row = 0; row < 4; row++) {
    for (int col = 0; col < 4; col++) {
      if (SHAPES[type][rotation][row][col]) {
        int gridX = x + col;
        int gridY = y + row;

        // 检查边界
        if (gridX < 0 || gridX >= GRID_WIDTH || gridY >= GRID_HEIGHT) {
          return false;
        }

        // 检查是否与已有方块重叠（gridY < 0 允许方块从顶部出现）
        if (gridY >= 0 && grid[gridY][gridX] > 0) {
          return false;
        }
      }
    }
  }
  return true;
}

// 生成新方块
void Tetris::spawnTetromino() {
  currentType = nextType;
  nextType = random(TETROMINO_TYPES);
  currentRotation = 0;
  currentX = GRID_WIDTH / 2 - 2;
  currentY = 0;

  // 检查游戏是否结束
  if (!canMove(currentType, currentRotation, currentX, currentY)) {
    gameOver = true;
  }
}

// 锁定当前方块到游戏区域
void Tetris::lockTetromino() {
  for (int row = 0; row < 4; row++) {
    for (int col = 0; col < 4; col++) {
      if (SHAPES[currentType][currentRotation][row][col]) {
        int gridX = currentX + col;
        int gridY = currentY + row;
        if (gridY >= 0 && gridY < GRID_HEIGHT && gridX >= 0 && gridX < GRID_WIDTH) {
          grid[gridY][gridX] = currentType + 1;  // 存储方块类型+1
        }
      }
    }
  }
}

// 消除满行
int Tetris::clearLines() {
  int linesCleared = 0;

  for (int y = GRID_HEIGHT - 1; y >= 0; y--) {
    bool fullLine = true;
    for (int x = 0; x < GRID_WIDTH; x++) {
      if (grid[y][x] == 0) {
        fullLine = false;
        break;
      }
    }

    if (fullLine) {
      linesCleared++;
      // 将上面的行下移
      for (int moveY = y; moveY > 0; moveY--) {
        for (int x = 0; x < GRID_WIDTH; x++) {
          grid[moveY][x] = grid[moveY - 1][x];
        }
      }
      // 清空最顶行
      for (int x = 0; x < GRID_WIDTH; x++) {
        grid[0][x] = 0;
      }
      y++;  // 重新检查当前行
    }
  }

  return linesCleared;
}

// 更新等级和速度
void Tetris::updateLevel() {
  int newLevel = (lines / 10) + 1;  // 每消除10行升一级
  if (newLevel != level) {
    level = newLevel;
    // 等级越高，下落越快
    dropInterval = max(100, 800 - (level - 1) * 80);
  }
}

// 方块下移
bool Tetris::moveDown() {
  if (canMove(currentType, currentRotation, currentX, currentY + 1)) {
    currentY++;
    return true;
  }
  return false;
}

// 方块左移
void Tetris::moveLeft() {
  if (canMove(currentType, currentRotation, currentX - 1, currentY)) {
    currentX--;
  }
}

// 方块右移
void Tetris::moveRight() {
  if (canMove(currentType, currentRotation, currentX + 1, currentY)) {
    currentX++;
  }
}

// 方块旋转
void Tetris::rotate() {
  int newRotation = (currentRotation + 1) % 4;
  if (canMove(currentType, newRotation, currentX, currentY)) {
    currentRotation = newRotation;
  } else {
    // 尝试墙踢（Wall Kick）- 向左或向右移动一格后旋转
    if (canMove(currentType, newRotation, currentX - 1, currentY)) {
      currentX--;
      currentRotation = newRotation;
    } else if (canMove(currentType, newRotation, currentX + 1, currentY)) {
      currentX++;
      currentRotation = newRotation;
    }
  }
}

// 快速下落
void Tetris::hardDrop() {
  while (moveDown()) {
    // 持续下落直到不能下落
  }
}

// ========== 输入处理 ==========

void Tetris::handleInput(Keys &keys) {
  unsigned long currentTime = millis();
  // static bool leftPressed = false;
  // static bool rightPressed = false;
  static bool downPressed = false;
  static bool rotatePressed = false;

  // 更新按键状态
  keys.kvs_update();

  // 暂停/继续
  if (keys.a.pressed()) {
    paused = !paused;
    delay(200);  // 防抖
  }

  if (paused) {
    return;
  }

  // 旋转
  if (keys.o.pressed() && !rotatePressed) {
    rotate();
    rotatePressed = true;
  } else if (!keys.o.pressed()) {
    rotatePressed = false;
  }

  // 左移 - 支持连续移动
  if (!keys.left.read() && currentTime - lastMoveTime > 100) {
    moveLeft();
    lastMoveTime = currentTime;
    // leftPressed = true;
  } else if (keys.left.read()) {
    // leftPressed = false;
  }

  // 右移 - 支持连续移动
  if (!keys.right.read() && currentTime - lastMoveTime > 100) {
    moveRight();
    lastMoveTime = currentTime;
    // rightPressed = true;
  } else if (keys.right.read()) {
    // rightPressed = false;
  }

  // 快速下落
  if (!keys.down.read()) {
    if (!downPressed || currentTime - lastMoveTime > 50) {
      moveDown();
      lastMoveTime = currentTime;
      downPressed = true;
    }
  } else {
    downPressed = false;
  }
}

// ========== 主游戏循环 ==========

void Tetris::main(Screen &screen, Keys &keys) {
  // 初始化游戏
  initGame();

  // 清屏并绘制初始界面
  screen.clearAndLeft();
  drawGameArea(screen);
  drawPreview(screen);
  drawInfo(screen);
  screen.drawScreen();

  // 游戏主循环
  while (!gameOver) {
    unsigned long currentTime = millis();

    // 处理输入
    handleInput(keys);

    // 检查是否退出
    if (keys.x.pressed()) {
      screen.clearAndCenter();
      return;
    }

    if (!paused) {
      // 自动下落
      if (currentTime - lastDropTime > dropInterval) {
        if (!moveDown()) {
          // 方块不能下落，锁定它
          lockTetromino();

          // 清除满行
          int linesCleared = clearLines();
          if (linesCleared > 0) {
            lines += linesCleared;
            // 计分：1行100分，2行300分，3行500分，4行800分
            int points[] = { 0, 100, 300, 500, 800 };
            score += points[min(linesCleared, 4)];
            updateLevel();
          }

          // 生成新方块
          spawnTetromino();

          // 更新预览
          drawPreview(screen);
        }
        lastDropTime = currentTime;
      }

      // 重绘游戏画面
      // 清除游戏区域
      screen.spr.fillRect(GAME_OFFSET_X, GAME_OFFSET_Y, GRID_WIDTH * BLOCK_SIZE, GRID_HEIGHT * BLOCK_SIZE, TFT_BLACK);

      // 绘制已锁定的方块
      drawGrid(screen);

      // 绘制当前方块
      drawCurrentTetromino(screen);

      // 更新信息显示
      drawInfo(screen);
    } else {
      // 暂停状态显示
      screen.spr.setTextColor(TFT_YELLOW, TFT_BLACK);
      screen.spr.setTextDatum(CC_DATUM);
      screen.spr.drawString("暂停", 70, 200, 4);
      screen.spr.setTextDatum(TL_DATUM);
    }

    // 更新屏幕
    screen.drawScreen();

    delay(10);  // 小延迟，降低CPU使用率
  }

  // 游戏结束
  drawGameOver(screen);
  screen.drawScreen();

  // 等待玩家选择
  while (true) {
    keys.kvs_update();

    if (keys.b.pressed()) {
      // 重新开始
      main(screen, keys);
      return;
    }

    if (keys.x.pressed()) {
      // 退出
      screen.clearAndCenter();
      return;
    }

    delay(10);
  }
}